import copy  # 深拷贝
import xlrd  # 打开表
import re  # 正则
import sys
import xlsxwriter  # 批量写入表
import datetime  # 时间处理

'''
在一个表中，纳税人识别号有重复，想按照多个条件的优先级去重。
0、打开数据表                     [[1], [3], [3], [2], [1], [4], [5], [4], [2], [5]]
1、对要去重的字段排序             [[1], [1], [2], [2], [3], [3], [4], [4], [5], [5]]
2、排序后重复数据分组             [[1], [1], [2], [2], [3], [3], [4], [4], [5], [5]]
3、对每组数据进行关联条件筛选    [[1], [2], [3], [4], [5]]
4、筛选结果写入表中               [[1], [2], [3], [4], [5]]

只需要对第三步 workGroup 方法中的if语句进行增改。
'''


# 'C:\Users\Seven\Desktop\新建文jh\11.xlsx' 为数据表路径
# 'C:\Users\Seven\Desktop\新建文jh\导出.xlsx' 为导出表路径


# 导入表，将excel表的数据变成要处理的数据形式。
def writeFile():
    book = xlrd.open_workbook(r'C:\Users\Seven\Desktop\新建文jh\11.xlsx')  # 打开需要操作的excel表
    sheet = book.sheet_by_index(0)  # 根据顺序获取sheet
    txtList = []  # 取出文件内数据
    dataList2 = []  # 生成文件数据
    for i in sheet.get_rows():
        txtList.append(i)

    for j in txtList:
        dataList1 = []
        for k in j:
            k = re.sub("'", "", str(k))
            a, b = k.strip().split(':')
            dataList1.append(b)
        dataList2.append(dataList1)
    return dataList2


# 分组操作，关联条件就写在这里
def workGroup(i, sum, data, datar):
    '''
    不用更改传递的参数，只需要把相应的关联条件写在这个函数里就可以。
    :param i:
    :param sum:
    :param data:
    :param datar:
    :return:
    '''
    f1 = data[i][0]
    dataList = []
    if sum > 1:  # 对组内数据大于1的组进行条件去重筛选，只有一条数据不需要去重，也就不需要条件过滤。
        for j in range(sum):
            num = i - j - 1

            # 1、对一组重复数据进行条件判断，这里反向判断，不符合条件的记录删除，保留了，该字段为空的情况。
            flag1 = data[num][2]
            if flag1 == '注销':
                datar[num] = None
                continue

            # 2、进行第二优先级条件判断。
            flag2 = data[num][31]
            if flag2 == '无效':
                datar[num] = None
                continue

            # 3_1、将该组中的所有数据的时间字段和索引加入dataList列表中
            flag3 = data[num][9]
            dataList.append([flag3, num])
        # 3_2、将只有单个的时间数据的过滤，找出最小的时间
        if len(dataList) > 1:
            timef = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            for i in dataList:
                timef = min(i[0], timef)
            for j in dataList:
                if j[0] != timef:
                    datar[j[1]] = None

    sum = 0  # 分组操作完毕，分组计数归零，重新开始计数。
    return [f1, sum, datar]


# 去重
def disdinct(data: list, disC: int):
    '''
    :param data: 操作数据[[], [], []]或者[(), (), ()] 格式
    :param disC: 重复字段索引位置 0 开始
    :return: 返回根据条件去重后字段。
    '''

    # 获取列表的需要排序的字段进行排序
    def takeSecond(elem):
        return elem[disC]

    data.sort(key=takeSecond)  # 排序
    # 工具定义
    f1 = ''  # 去重字段
    sum = 0  # 分组计数
    datar = copy.deepcopy(data)  # 新建操作数据
    Lendata = len(data)  # 数据长度

    # 遍历全部数据
    # 开始操作
    for i in range(len(data)):
        # 初始化赋值
        if f1 == '':
            f1 = data[i][0]
        # 每当遇到不同值时候，说明以上为同一组重复纳税人数据。通过分组计数sum来定位操作。
        if f1 != data[i][0]:
            wG = workGroup(i, sum, data, datar)
            f1 = wG[0]
            sum = wG[1]
            datar = wG[2]

        sum += 1  # 组内数据加1

    # 以上循环结束后，最后一组数据未操作，将以上同组执行的操作再次执行一遍。
    wG1 = workGroup(Lendata - 1, sum, data, datar)
    datar = wG1[2]

    # 所有操作完成后，对None的数据进行删除。
    Rdata = []
    for i in datar:
        if i != None:
            Rdata.append(i)

    return Rdata


# 写入文件
def Wfile(listOut):
    workbook = xlsxwriter.Workbook(r'C:\Users\Seven\Desktop\新建文jh\导出.xlsx', {'constant_memory': True})
    worksheet = workbook.add_worksheet(name='导出')  # 表单名称

    for line in enumerate(listOut):
        n, value = line[0], line[1]
        for i in range(len(value)):
            v = [value[i]]
            worksheet.write_row(n, i, v, cell_format=None)
    workbook.close()
    print('导出表生成成功' + r'C:\Users\Seven\Desktop\新建文jh\导出.xlsx')


if __name__ == '__main__':
    Wfile(disdinct(writeFile(), 0))
    '''
    writeFile（）：读取文件
    disdinct(writeFile(), 0)：将读取的文件和要去重的字段索引位置传入去重函数
    Wfile(disdinct(writeFile(), 0))：将去重结果写入表
    '''
    sys.exit()
